#include <Python.h>
#include <structmember.h>
#include <iostream>

typedef struct {
    PyObject_HEAD
    int value;
} MyObject;

// 自定义构造函数（对应 __new__）
static PyObject* MyObject_new(PyTypeObject* type, PyObject* args, PyObject* kwds);

static void MyObject_dealloc(MyObject* self) {
    std::cout << "MyObject_dealloc (C++ destructor) called!" << std::endl;
    Py_TYPE(self)->tp_free((PyObject*)self);  // 释放内存
}

// 自定义初始化函数（对应 __init__）
static int MyObject_init(MyObject* self, PyObject* args, PyObject* kwds) {
    std::cout << "MyObject_init (C++ initializer) called!" << std::endl;
    static const char* kwlist[] = {"value", NULL};
    int value = 0;
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i", (char**)kwlist, &value))
        return -1;
    self->value = value;
    return 0;
}

// 2. 定义方法
static PyObject* MyObject_add(MyObject* self, PyObject* args) {
    int num;
    if (!PyArg_ParseTuple(args, "i", &num))  // 解析 Python 传入的参数
        return NULL;
    self->value += num;
    Py_RETURN_NONE;  // 返回 Python 的 None
}

// 3. 定义成员（属性）
static PyGetSetDef MyObject_getset[] = {
    {"value", 
     [](PyObject* self, void*) -> PyObject* {
         return PyLong_FromLong(((MyObject*)self)->value);
     },
     [](PyObject* self, PyObject* value, void*) -> int {
         if (!PyLong_Check(value)) {
             PyErr_SetString(PyExc_TypeError, "value must be an integer");
             return -1;
         }
         ((MyObject*)self)->value = PyLong_AsLong(value);
         return 0;
     },
     "An integer value"},
    {NULL}
};

// 方法定义（保持不变）
static PyMethodDef MyObject_methods[] = {
    {"add", (PyCFunction)MyObject_add, METH_VARARGS, "Add a number to value"},
    {NULL}
};

// 更新类型对象
static PyTypeObject MyObjectType = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "mydemo.MyObject",          // tp_name
    sizeof(MyObject),           // tp_basicsize
    0,                          // tp_itemsize
    (destructor)MyObject_dealloc, // tp_dealloc
    0,                          // tp_vectorcall_offset
    0,                          // tp_getattr
    0,                          // tp_setattr
    0,                          // tp_as_async
    0,                          // tp_repr
    0,                          // tp_as_number
    0,                          // tp_as_sequence
    0,                          // tp_as_mapping
    0,                          // tp_hash
    0,                          // tp_call
    0,                          // tp_str
    0,                          // tp_getattro
    0,                          // tp_setattro
    0,                          // tp_as_buffer
    Py_TPFLAGS_DEFAULT 
    | Py_TPFLAGS_BASETYPE,      // tp_flags
    "My custom object",         // tp_doc
    0,                          // tp_traverse
    0,                          // tp_clear
    0,                          // tp_richcompare
    0,                          // tp_weaklistoffset
    0,                          // tp_iter
    0,                          // tp_iternext
    MyObject_methods,           // tp_methods
    0,                          // tp_members
    MyObject_getset,            // tp_getset
    0,                          // tp_base
    0,                          // tp_dict
    0,                          // tp_descr_get
    0,                          // tp_descr_set
    0,                          // tp_dictoffset
    (initproc)MyObject_init,    // tp_init
    0,                          // tp_alloc
    MyObject_new,               // tp_new
};


// 6. 模块初始化
static PyModuleDef mydemomodule = {
    PyModuleDef_HEAD_INIT,
    "mydemo",                   // 模块名
    "A demo module",            // 文档
    -1,                         // 全局状态大小
    nullptr                     // 模块方法表
};

PyMODINIT_FUNC PyInit_mydemo() {
    PyObject* m;
    if (PyType_Ready(&MyObjectType) < 0)  // 初始化类型
        return NULL;

    m = PyModule_Create(&mydemomodule);
    if (m == NULL)
        return NULL;

    Py_INCREF(&MyObjectType);
    PyModule_AddObject(m, "MyObject", (PyObject*)&MyObjectType);  // 暴露类
    return m;
}

// 自定义构造函数（对应 __new__）
static PyObject* MyObject_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
    std::cout << "MyObject_new (C++ constructor) called! " << std::boolalpha << (type == &MyObjectType) << std::endl;
    MyObject* self = (MyObject*)type->tp_alloc(type, 0);  // 分配内存
    if (self != NULL) {
        self->value = 0;  // 默认初始化
    }
    return (PyObject*)self;
}
